"""
@File    : decorators.py.py
@Time    : 2025/7/17 下午4:17
@Author  : xiashuobad
@Desc    : 

/**
 * _ooOoo_
 * o8888888o
 * 88" . "88
 * (| -_- |)
 *  O\ = /O
 * ___/`---'\____
 * .   ' \\| |// `.
 * / \\||| : |||// \
 * / _||||| -:- |||||- \
 * | | \\\ - /// | |
 * | \_| ''\---/'' | |
 * \ .-\__ `-` ___/-. /
 * ___`. .' /--.--\ `. . __
 * ."" '< `.___\_<|>_/___.' >'"".
 * | | : `- \`.;`\ _ /`;.`/ - ` : | |
 * \ \ `-. \_ __\ /__ _/ .-` / /
 * ======`-.____`-.___\_____/___.-`____.-'======
 * `=---=' bug泛滥 佛已瘫痪
"""
import logging
from functools import wraps
from inspect import signature
from typing import get_type_hints, Any, Union, List, _GenericAlias, Dict, Literal, Tuple
from types import UnionType, GenericAlias

from .misc import try_import
from .exceptions import NoImageDataError

logger = logging.getLogger(__name__)


def handle_func_errors(default_return=None):
    """装饰器：统一处理图片相关函数运行异常，返回 default_return"""

    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                logger.warning(f"[yellow] 函数 {func.__name__} 执行失败: {e}", extra={'markup': True})
                return default_return

        return wrapper

    return decorator


def require_attr_not_empty(attr_name: str):
    """带参数的装饰器，确保运行实例方法时，实例中的指定属性不为空，否则抛出异常"""

    def decorator(method):
        @wraps(method)
        def wrapper(instance, *args, **kwargs):
            if getattr(instance, attr_name, None) is None:
                raise NoImageDataError(f"属性：{attr_name} 为空，无法执行方法:{method}！")
            return method(instance, *args, **kwargs)

        return wrapper

    return decorator


def require_python_library(module_name: str, library_name: str = None):
    """带参数的装饰器，确保运行某实例方法时，已经安装了某个库"""

    def decorator(method):
        @wraps(method)
        def wrapper(instance, *args, **kwargs):
            if not try_import(module_name):
                raise ImportError(f"请先安装：{library_name or module_name} 库！")
            return method(instance, *args, **kwargs)

        return wrapper

    return decorator


def type_check(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        sig = signature(func)
        bound_args = sig.bind(*args, **kwargs)
        bound_args.apply_defaults()

        # 获取类型注解
        type_hints = get_type_hints(func)

        for name, value in bound_args.arguments.items():
            expected_type = type_hints.get(name)
            if expected_type is None:
                continue  # 无类型注解，跳过检查

            _validate_type(name, value, expected_type)

        return func(*args, **kwargs)

    return wrapper


def _validate_type(name: str, value: Any, expected_type: type):
    if value is None or isinstance(value, type(...)):
        return
    ori_expected_type = expected_type
    # 处理Literal类型
    if getattr(expected_type, '__origin__', expected_type) is Literal:
        args = expected_type.__args__
        if value not in args:
            raise TypeError(f'{name} 的值必须是 {args} 其中之一，但实际为 {value}')
        return

    origin = getattr(expected_type, '__origin__', expected_type)

    # 处理 Union 类型（包括 Optional）
    if origin is Union or isinstance(expected_type, UnionType):
        # 获取非泛型的基本类型用于 isinstance 检查
        valid_types = []
        for t in expected_type.__args__:
            # 获取基本类型
            base_type = getattr(t, '__origin__', t)
            if base_type is tuple:
                base_type = tuple
            elif base_type is list:
                base_type = list
            elif base_type is dict:
                base_type = dict
            valid_types.append(base_type)

        if not any(isinstance(value, t) for t in valid_types):
            raise TypeError(f"参数 {name} 的类型必须是 {ori_expected_type}，实际为 {type(value)}")
        return

    # 处理其他泛型类型
    if isinstance(expected_type, (_GenericAlias, GenericAlias)) or origin is not None:
        # 简化处理，只检查基本类型
        if origin is tuple or origin is Tuple:
            if not isinstance(value, tuple):
                raise TypeError(f"参数 {name} 必须是 tuple 或 list 类型，实际为 {type(value)}")
            return
        elif origin is list or origin is List:
            if not isinstance(value, list):
                raise TypeError(f"参数 {name} 必须是 list 类型，实际为 {type(value)}")
            return
        elif origin is dict or origin is Dict:
            if not isinstance(value, dict):
                raise TypeError(f"参数 {name} 必须是 dict 类型，实际为 {type(value)}")
            return

    # 基本类型检查
    if not isinstance(value, expected_type):
        raise TypeError(f"参数 '{name}' 的类型必须是 {expected_type}，实际为 {type(value)}")
